/********************************************************************************
* @file    bsp_owire.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-11-22
* @brief   单总线协议(One-Wire)  目前用来控制ws2812通信
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#include "RTE_Components.h"
#include CMSIS_device_header

#include "cx32l003_hal_def.h"
#include "cx32l003_hal_conf.h"
#include "bsp_exti.h"
/* Private Includes ----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/
/* Private Variables ---------------------------------------------------------*/
bool bsp_owire_init = false;
bool bsp_owire_bus = false;

const OWIRE_HandleTypeDef g_owire_handler =
{
    .Instance                  = OWIRE,
    .Init.ClockDiv             = OWIRE_CLOCK_DIVIDER_1,        // 时钟源分频
    .Init.FirstBit             = OWIRE_FIRSTBIT_LSB,           // 字节发送的位模式
    .Init.DataSize             = OWIRE_DATASIZE_8BIT,          // 单次处理数据8位
    .Init.ReadMode             = OWIRE_RDMODE_0,               // 普通模式
    .Init.NoiseFilterEn        = OWIRE_NOISE_FILTER_DISABLE,   // 输入端子滤波功能禁止
    .Init.NoiseFilterClk       = OWIRE_NOISE_FILTER_CLK_DIV_1, // 输入端子滤波时钟源预分频
    .Init.ResetCounter         = 240,                          // 主发送复位时间设定计数值 (480us~960us)
    .Init.PresencePulseCounter = 60,                           // 从应答时间设定计数值(60us~240us) 
    .Init.BitRateCounter       = 1,                            // 设置1Bit数据宽度(1us~60us)
    .Init.DriveCounter         = 0,                            // 主器件读/写PULL0驱动时间设定计数值(0us~15us)
    .Init.ReadSamplingCounter  = 1,                            // 设置读采样时间(1us~15us)
    .Init.RecoverCounter       = 1                             // 设置RECOVER时间为(TREC>1us)
};
/* Public Function Prototypes ------------------------------------------------*/

void HAL_OWIRE_TxCpltCallback(OWIRE_HandleTypeDef *howire)
{
    bsp_owire_bus = false;
}

/**
  * @brief  OWIRE MSP Init.
  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  */
void HAL_OWIRE_MspInit(OWIRE_HandleTypeDef *howire)
{
    /**One-Wire GPIO Configuration */
    GPIO_InitTypeDef GPIO_InitStruct = {
        .Pin             = GPIO_PIN_2,              // GPIO选择
        .Mode            = GPIO_MODE_AF,            // 复用功能选择
        .OpenDrain       = GPIO_OPENDRAIN,          // 开漏输出
        .Debounce.Enable = GPIO_DEBOUNCE_DISABLE,   // 禁止输入去抖
        .SlewRate        = GPIO_SLEW_RATE_HIGH,     // 电压转换速率
        .DrvStrength     = GPIO_DRV_STRENGTH_HIGH,  // 驱动强度
        .Pull            = GPIO_PULLUP,             // 上拉
        .Alternate       = GPIO_AF7_1WIRE,          // 复用AF7_1WIRE
    };
    /* Peripheral clock enable */
    __HAL_RCC_OWIRE_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

/**
 * @brief  通过onewire发送一组数据
 * @param  *data: 数据指针
 * @param  len: 数据长度
 */
bool bsp_onewire_send_data(uint8_t *data, uint16_t len)
{
    if (!bsp_owire_init || bsp_owire_bus)
    {
        return false;
    }
    bsp_owire_bus = true;
    HAL_OWIRE_Transmit_IT((OWIRE_HandleTypeDef *)&g_owire_handler, data, len);
    return true;
}

void bsp_onewire_init(void)
{
    if (bsp_owire_init)
    {
        return;
    }
    bsp_owire_init = true;
    HAL_OWIRE_Init((OWIRE_HandleTypeDef *)&g_owire_handler);
    bsp_exit_set(OWIRE_IRQn, 0);
    bsp_owire_bus = false;
}
